package com.online.olsrootserver.handler;

import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.mp.api.WxMpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * Created by littleheng on 2018/5/3
 */
@Component
public class WxMediaHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    // 图片存储地址
    @Value("${uploadDir}")
    private String uploadDir;

    // 端口号
    @Value("${server.port}")
    private String port;

    // 服务器地址
    @Value("${domain.name}")
    private String address;

    @Autowired
    private WxMpService wxService;

    /**
     * 图片上传
     * @param mediaId 微信媒体文件id
     * @param request
     * @return
     */
    public Map uploadImage(String mediaId, HttpServletRequest request) {

        Map<String, Object> map = new HashMap<>();

        String filename = "";
        if (!"".equals(mediaId)) {
            Map<String, String> param = new HashMap<>();
            param.put("mediaId", mediaId);

            Map result = this.wxMediaDownload(param);
            if (Integer.parseInt(result.get("result").toString()) == 0) {
                String path = result.get("file").toString();
                File file = new File(path);
                try {
                    InputStream fis = new FileInputStream(file);
                    filename = file.getName();
                    this.readStream(fis, filename);
                    filename = address + ":" + port + "/" + filename;
                    map.put("result", 0);
                    map.put("url", filename);
                } catch (Exception e) {
                    System.out.println(e.getMessage() + "\n文件上传失败");
                    map.put("result", 1);
                }
            } else {
                this.logger.info("微信图片下载失败");
                map.put("result", 1);
            }
        } else {
            try {
                request.setCharacterEncoding("utf-8");

                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;

                Iterator<String> iterator = multipartRequest.getFileNames();

                while (iterator.hasNext()) {
                    String name = iterator.next();
                    MultipartFile file = multipartRequest.getFile(name);
                    filename = file.getOriginalFilename();
                    InputStream inStream = file.getInputStream();
                    this.readStream(inStream, filename);

                    File uploadFile = new File(uploadDir + filename);

                    Map<String, Object> param = new HashMap<>();
                    param.put("mediaType", "image");
                    param.put("file", uploadFile);

                    Map result = this.wxMediaUpload(param);
                    if (Integer.parseInt(result.get("result").toString()) == 0) {
                        this.logger.info("上传微信图片成功");
                        filename = address + ":" + port + "/" + filename;
                        map.put("result", 0);
                        map.put("url", filename);
                        map.put("media_id", result.get("media_id"));
                    } else {
                        map.put("result", 1);
                        this.logger.info("上传微信图片失败");
                    }
                }
            } catch (Exception e) {
                map.put("result", 1);
                System.out.println(e.getMessage() + "\n文件上传失败");
            }
        }
        return map;
    }

    /**
     * 写入文件
     * @param inStream
     * @param name
     * @throws Exception
     */
    private void readStream(InputStream inStream, String name) throws Exception{
        FileOutputStream outStream = null;
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            outStream = new FileOutputStream(uploadDir + name);
            while((len=inStream.read(buffer))!=-1){
                outStream.write(buffer,0,len);
            }
            outStream.flush();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        outStream.close();
        inStream.close();
    }

    /**
     * 新增微信临时素材
     * @param map
     * mediaType 媒体文件类型：图片(image)、语音(voice)、视频(video)、缩略图(thumb)
     * file 文件
     * @return
     */
    private Map wxMediaUpload(Map map) {
        String mediaType = map.get("mediaType").toString();
        File file = new File(map.get("file").toString());

        WxMediaUploadResult res = null;
        try {
            res = this.wxService.getMaterialService()
                    .mediaUpload(mediaType, file);
        } catch (Exception e) {
            this.logger.info(e.getMessage(), e);
        }

        Map<String, Object> maps = new HashMap<>();
        maps.put("result", res != null ? "0" : "1");
        maps.put("type", res != null ? res.getType() : "" );
        maps.put("media_id", res != null ? res.getMediaId(): "");
        maps.put("created_at", res != null ? res.getCreatedAt() : 0);
        maps.put("thumb_media_id", res != null ? res.getThumbMediaId() : "" );

        return maps;
    }

    /**
     * 获取微信临时素材
     * @param map
     * mediaId 媒体id
     * @return
     */
    private Map wxMediaDownload(Map map) {
        String mediaId = map.get("mediaId").toString();

        Map<String, Object> maps = new HashMap<String, Object>();
        File file = null;
        try {
            file = this.wxService.getMaterialService().mediaDownload(mediaId);
            maps.put("result", "0");
            maps.put("file", file);
        } catch (Exception e) {
            maps.put("result", "1");
            this.logger.info(e.getMessage(), e);
        }
        return maps;
    }
}